package com.manager.common.tcp.server;

import com.manager.common.tcp.constant.TcpDataType;
import com.manager.common.tcp.decode.impl.BusinessDecode;
import com.manager.common.tcp.encode.impl.BusinessEncode;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;

public class TcpServer {

    private static final Logger logger = LoggerFactory.getLogger(TcpServer.class);

    private static LinkedBlockingQueue<BusinessDecode> receiptQueue = new LinkedBlockingQueue<BusinessDecode>();

    private static TcpServer tcpServer = new TcpServer();

    private static Object lock = new Object();

    private Channel clientChannel;

    private TcpServer() {

    }

    public final static TcpServer getInstance() {
        return tcpServer;
    }

    public void start(int tcpServerPort) {
        //用于服务器端接受客户端的连接
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //用于网络事件的处理
        NioEventLoopGroup workGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new TcpServerChannel())
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture channelFuture = serverBootstrap.bind(tcpServerPort).sync();
            System.out.println("Server started on port " + tcpServerPort);
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }

    public Channel getClientChannel() {
        synchronized (lock) {
            return clientChannel;
        }
    }

    public void setClientChannel(Channel clientChannel) {
        synchronized (lock){
            this.clientChannel = clientChannel;
        }
    }

    public static void main(String[] args) {


       TcpServer tcpServer = TcpServer.getInstance();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try{
                        Random random = new Random();
                        int date = random.nextInt(10) * 1000;
                        int type = random.nextInt(7) + 1;
                        Thread.sleep(date);
                        if(tcpServer.getClientChannel() == null){
                            continue;
                        }
                        String str = "{\"serialNumber\":\"1757926276\",\"filepath\":\"/opt/data/1757984954078_6.json\",\"type\":"+type+"}";
                        BusinessEncode businessEncode = new BusinessEncode(TcpDataType.TCP_FILE_REPORT);
                        tcpServer.getClientChannel().writeAndFlush( businessEncode.encode(str));
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        tcpServer.start(6538);

    }
}
